/**
 * 育儿网问 详情
 */

const puppeteer = require('puppeteer');
const fs = require("fs");
const readline = require('readline');
const lockfile = require('lockfile');

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

const timestart = new Date().getTime();

(async() => {
	let browser = null;
	// 每行一页
	rl.on('line', async(line)=>{
		if (!browser){
			// 默认启动内嵌的 chrome
			browser = await puppeteer.launch(
				{args: ['--no-sandbox']}
			);
		}
		const list = JSON.parse(line);
		// 并行任务
		let ptask = [];
		list.forEach(item=>{
			if (!item.url.startsWith('http')){
				item.url = 'http://ask.ci123.com' + item.url;
			}
			item.url = item.url.replace('show', 'shows');
			ptask.push((async()=>{
			    try {
				// 修改 runningJob 先锁定
				while (!idle()){
					await sleep(250);
				}
				const page = await browser.newPage();
				await page.setRequestInterception(true);
				page.on('request', interceptedRequest => {
					const url = interceptedRequest.url().toLowerCase();
					for (name of ['.jpg', '.jpeg', '.png', '.gif']){
						if (url.endsWith(name)){
							// 终止请求
							interceptedRequest.abort();
							return ;
						}
					}
					interceptedRequest.continue();
				});
				await page.setJavaScriptEnabled(false);
				// 打开详情页
				await page.goto(item.url, {waitUntil: 'domcontentloaded'});
				// 抽标题
				const titleHdl = await page.$x('.//*[@class="a_green"]/*[@class="ask2_inner"][1]//h3/text()');
				const title = await textValue(titleHdl[0]);
				item.title = title;
				// question
				const queHdl = await page.$x('.//*[@class="a_green"]/*[@class="ask2_inner"][1]//td[h3]/span/text()');
				const question = await textValue(queHdl[0]);
				item.question = question;
				// answers
				const ansHdl = await page.$x('.//*[@class="a_green"]/div/*[@class="ask2_inner"]|.//*[@class="a_green"]/*[@class="ask2_inner" and position()>1]');
				item.answers = [];
				for (answHdl of ansHdl){
					// 回答
					const answerHdl = await answHdl.$x('.//td/span/text()');
					const answer = await textValue(answerHdl[0]);
					// 日期
					const dateHdl = await answHdl.$x('.//tr[2]/td/p/text()');
					const date = (await textValue(dateHdl[0])).trim();
					// 作者
					const authorHdl = await answHdl.$x('.//tr[1]/td[1]/p[1]/a/text()');
					const author = await textValue(authorHdl[0]);
					// 是否采纳
					const bestHdl = await answHdl.$x('.//h3[@class="good"]');
					const isBest = bestHdl != null && bestHdl.length > 0;
					item.answers.push({answer, date, author, isBest})
				}	
				//await page.close();
				relex();
			    } catch (e){
				console.log(item.url, e);
				//await page.close();
				relex();
			    }
			})());
		});
		await Promise.all(ptask);
		// 保存文件
		const savePath = 'dat/ask.ci123.com_all.json';
		fs.writeFile(savePath, JSON.stringify(list)+"\n", {
				encoding: 'utf8',
				mode: 0666,
				flag: 'a'
			}, err=>{
			if (err){
				return console.error(err);
			}
		})
		
		// close browser
		//await browser.close();	

		const timeend = new Date().getTime();
		console.log(timestart, timeend, timeend - timestart);
	})// *rl
	
	

})();

async function textValue(jsHandle){
	const text = await jsHandle.executionContext().evaluate(e=> e.textContent, jsHandle);
	return text;
}

let runningJob = 0;
const filelock = '.lock',
	maxRunning = 5;
function idle(){
	lockfile.lockSync(filelock);
	if (runningJob < maxRunning){
		runningJob += 1;
		lockfile.unlockSync(filelock);
		return true;
	}
	lockfile.unlockSync(filelock);
	return false;
}
function relex(){
	lockfile.lockSync(filelock);
	runningJob -= 1;
	lockfile.unlockSync(filelock);
}
function sleep(time){
    return new Promise(function (resolve, reject) {
        setTimeout(function () {
            resolve();
        }, time);
    })
}
